import {Component, ComponentFactoryResolver, ComponentRef, EmbeddedViewRef, Injector, NgModuleRef, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation, ViewRef} from '@angular/core';
import {AppService} from "./app.service";
import {GlobalEvent} from './support/event.definition';
import {animate, AnimationBuilder, state, style, transition, trigger} from "@angular/animations";
import {MainComponent} from "./application/main.component";
import {LoginComponent} from "./application/login/login.component";
import {NoticeComponent} from "./application/common/sidebar/notice/notice.component";
import {ProcedureComponent} from "./application/common/sidebar/procedure/procedure.component";
import {AppDefinitionRefs} from "./app.definition";


@Component({
  selector: 'ss-platform-wraper',
  templateUrl: `./app.component.html`,
  styleUrls: ['./app.component.scss'],
  animations: [
    trigger("toggle", [
      state('false', style({transform: 'translate3d(0px,0,0)'})),
      state('true', style({transform: 'translate3d(-320px,0,0)'})),
      transition("false <=> true", animate(200))
    ])
  ],
  host: {class: "ss-platform-wraper"},
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {

  @ViewChild("viewContainer", {read: ViewContainerRef, static: true})
  private viewContainerRef: ViewContainerRef;
  private componentRefs: Array<ComponentRef<any>> = [];

  constructor(private resolver: ComponentFactoryResolver, private $app: AppService) {
    let self = this;
    // 动态加载组件
    $app.subscribe(Object.keys(AppDefinitionRefs).concat(GlobalEvent.HideSidebar), (eventName, data, resolve) => {
      // 隐藏侧面板
      if (eventName == GlobalEvent.HideSidebar) {
        self.componentRefs.filter(componentRef => componentRef.instance instanceof NoticeComponent || componentRef.instance instanceof ProcedureComponent).forEach(componentRef => {
          self.destroyComponent(componentRef.instance);
        })
      }
      // 常规加载
      else {
        // MainComponent 与 LoginComponent 互斥
        if ([GlobalEvent.ShowMain, GlobalEvent.ShowLogin].indexOf(eventName) > -1) {
          self.componentRefs.filter(componentRef => componentRef.instance instanceof MainComponent || componentRef.instance instanceof LoginComponent).forEach(componentRef => {
            self.destroyComponent(componentRef.instance);
          });
        }
        let componentRef = self.loadComponent(AppDefinitionRefs[eventName]);
        componentRef.instance.sourceEventData = data;
        componentRef.instance.sourceEventResolve = resolve;
        componentRef.instance.sourceEventName = eventName;
      }
    });
  }

  loadComponent(component: any, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<any> {
    let self = this,
      componentRef = self.viewContainerRef.createComponent(self.resolver.resolveComponentFactory(component), self.viewContainerRef.length, injector, projectableNodes, ngModule);
    self.componentRefs.push(componentRef);
    return componentRef;
  }

  destroyComponent(componentInstance: any): void {
    let self=this;
    self.componentRefs.filter(componentRef => (componentRef.instance == componentInstance)).forEach(componentRef => {
      componentRef.destroy();
    });
  }

  createEmbeddedView(templateRef: TemplateRef<any>, context?, index?: number): EmbeddedViewRef<any> {
    let self=this;
    return self.viewContainerRef.createEmbeddedView(templateRef, context, index);
  }

  ngOnInit(): void {
    // 系统初始化完成、数据加载完毕
    let self=this;
    let isLogin: boolean = true;
    // 已登录
    if (!isLogin) {
      self.$app.publish(GlobalEvent.ShowLogin);
    }
    // 未登录
    else {
      self.$app.publish(GlobalEvent.ShowMain);
    }

    // 模态窗口测试
    if (false) {
      setTimeout(() => {
        self.$app.publish(GlobalEvent.ShowMsgboxLeave, {items: [1, 2, 3]}).then(response => {
          console.log(response);
        })
        /*setTimeout(() => {
          self.$app.publish(GlobalEvent.ShowMsgboxLeave, {items: [1, 2, 3]}).then(response => {
            console.log(response);
          })
        }, 2000)*/
      })
    }
  }

}
